/**
 * Copyright (C) 2013 Oleg Anastassov <oleg.anastassov@gmail.com>
 *
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements. See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package kz.kstu.loc.business.patch;

import kz.kstu.loc.entity.Item;
import kz.kstu.loc.util.StringUtils;
import kz.kstu.loc.util.logger.Logger;
import org.apache.commons.io.FileUtils;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * Date: 17.01.2013
 * Time: 17:02
 *
 * @author Oleg Anastassov
 */
public class Patcher {

    private static final Logger LOGGER = Logger.getLogger(Patcher.class);

    public long patch(File file, List<Item> items) {
        return patch(file, items, true);
    }

    public long patch(File file, List<Item> items, boolean saveOriginal) {
        if (saveOriginal) {
            saveOriginalFile(file);
        }

        // TODO: Оптимизировать алгоритм.
        long totalLines = 0;
        long patchedCount = 0;
        try {
            File tmpFile = new File("tempFile.tmp");
            Writer out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpFile), "UTF-8"));

            InputStream fis = new FileInputStream(file);
            DataInputStream in = new DataInputStream(fis);
            BufferedReader br = new BufferedReader(new InputStreamReader(in));
            String origLine;
            while ((origLine = br.readLine()) != null) {
                totalLines++;
                Item found = getMatchedItem(origLine, items);
                if (found != null && !StringUtils.isEmptyOrNull(found.getValueKaz())) { // найден и есть перевод
                    String newLine = origLine.replaceAll("=.+$", "=" + found.getValueKaz());
                    LOGGER.info("Replacing value for key=''{0}'', set new value=''{1}''", found.getKey(), found.getValueKaz());
                    patchedCount++;
                    out.write(newLine);
                    out.write("\n");
                } else {
                    out.write(origLine);
                    out.write("\n");
                }
            }
            in.close();
            out.close();

            if (patchedCount > 0) {
                file.delete();
                tmpFile.renameTo(file);
            }

        } catch (Exception e) {
            LOGGER.error("Error: ", e);
        } finally {
            LOGGER.info("Total patched={0}", patchedCount);
            LOGGER.info("Total lines={0}", totalLines);
        }
        return patchedCount;
    }

    private Item getMatchedItem(String line, List<Item> items) {
        if (!StringUtils.isEmptyOrNull(line)) {
            int index = line.indexOf("=");
            if (index != -1) { // в строке есть символ '='
                String extractedKey = line.substring(0, index);
                String trimmedKey = extractedKey.trim();
                for (Item item : items) {
                    if (item.getKey().equals(trimmedKey)) {
                        return item;
                    }
                }
            }
        }
        return null;
    }

    /**
     * Только для тестирования.
     *
     * @param file копия оригинального файла с новым именем "copy-of-original.copy"
     */
    private void saveOriginalFile(File file) {
        String backupName = getBackupFileName(file, new Date());
        try {
            FileUtils.copyFile(file, new File(backupName));
        } catch (IOException e) {
            LOGGER.error("Error: ", e);
        }
    }

    private String getBackupFileName(File origFile, Date date) {
        String path = origFile.getAbsolutePath();
        int dotIndex = path.lastIndexOf(".");
        String origName = path.substring(0, dotIndex);
        String origExt = path.substring(dotIndex);
        return origName + "_backup_" + new SimpleDateFormat("yyyy-MM-dd HH_mm_ss_ms").format(date) + origExt;
    }

}
